package ourfilter;

import interfaces.Writeable;
import interfaces.Readable;

import java.io.StreamCorruptedException;
import java.security.InvalidParameterException;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

import pipes.Pipe;
import TransferObjekts.Line;
import TransferObjekts.Word;
import filter.AbstractFilter;

public class TokenizerFilter extends AbstractFilter<Line, Word> {

	private Queue<Word> buffer;
	private Readable<Line> in;
	private Writeable<Word> out;
	private boolean endOfStreamHasReached = false;

	public TokenizerFilter(Pipe<Line> in, Pipe<Word> out) throws InvalidParameterException {
		super(in, out);
		in.setOut(this);
		out.setIn(this);
		this.in = in;
		this.out = out;
		buffer = new LinkedList<Word>();
	}

	private void prozess(Line line) {
		StringTokenizer tokenizer = new StringTokenizer(line.getLine());
		while (tokenizer.hasMoreElements()) {
			buffer.add(new Word((String) tokenizer.nextElement(), line.getLineNumber()));
		}
	}

	@Override
	public Word read() throws StreamCorruptedException {
		if (buffer.isEmpty()) {
			Line val = in.read();

			if (val.getLine() == null) {
				buffer.add(null);
			} else {
				if (val.getLine().equals("")) {
					do {
						val = in.read();
					} while (val.getLine().equals(""));
					prozess(val);
				} else {
					prozess(val);
				}
			}
		}
		return buffer.poll();
	}

	@Override
	public void write(Line val) throws StreamCorruptedException {
		if (val.getLine() == null) {
			buffer.add(null);
			Word w;
			int curSize = buffer.size();
			for (int i = 0; i < curSize; i++) {
				w = buffer.poll();
				out.write(w);
			}
		} else {
			prozess(val);
			out.write(buffer.poll());
		}

	}

	@Override
	public void run() {
	}

}
